package com.heiye.blog.ai.servie.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.heiye.blog.ai.domain.dos.*;
import com.heiye.blog.ai.domain.mapper.*;
import com.heiye.blog.ai.enums.CapabilityLabelEnum;
import com.heiye.blog.ai.enums.ResponseCodeEnum;
import com.heiye.blog.ai.enums.RoleNameEnum;
import com.heiye.blog.ai.event.RoleServiceSoundGenerationEvent;
import com.heiye.blog.ai.factory.RoleStrategyFactory;
import com.heiye.blog.ai.model.dto.*;
import com.heiye.blog.ai.model.vo.*;
import com.heiye.blog.ai.servie.RoleService;
import com.heiye.blog.ai.strategy.role.RoleStrategy;
import com.heiye.blog.framework.common.exception.BizException;
import com.heiye.blog.framework.common.response.Response;
import com.heiye.blog.framework.mybatis.response.PageResponse;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import reactor.core.publisher.Flux;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: heiye
 * @date: 2025/11/05 下午7:35
 * @version: v1.0.0
 * @description: 智能体业务
 */
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RobotMapper robotMapper;

    @Resource
    private RobotCapabilityLabelMapper robotCapabilityLabelMapper;

    @Resource
    private CapabilityLabelMapper capabilityLabelMapper;

    @Resource
    private RobotTextMapper robotTextMapper;

    @Resource
    private TextModelMapper textModelMapper;

    @Resource
    private RobotSoundMapper robotSoundMapper;

    @Resource
    private SoundModelMapper soundModelMapper;

    @Resource
    private RobotSoundLanguageMapper robotSoundLanguageMapper;

    @Resource
    private LanguageMapper languageMapper;

    @Resource(name = "aiTaskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private RoleStrategyFactory roleStrategyFactory;

    // 注入事件发布器
    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Resource
    private ChatMapper chatMapper;

    @Resource
    private ChatMessageMapper chatMessageMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 查询智能体列表
     *
     * @param findRolePageListReqVO
     * @return
     */
    @Override
    public PageResponse<FindRolePageListRspVO> findRolePageList(FindRolePageListReqVO findRolePageListReqVO) {
        // 获取当前页、以及每页需要展示的数据数量
        Long current = findRolePageListReqVO.getCurrent();
        Long size = findRolePageListReqVO.getSize();

        // 分页查询智能体列表
        Page<RoleDO> roleDOPage = robotMapper.selectPageList(current, size);

        // 获取数据
        List<RoleDO> roleDOS = roleDOPage.getRecords();


        // 判断分页结果是否为空
        if (CollUtil.isEmpty(roleDOS)) {
            return PageResponse.success(roleDOPage, null);
        }

        // 提取智能体 ID 构建列表
        List<Long> roleIds = roleDOS.stream().map(RoleDO::getId).toList();

        // 查询该智能体支持的功能
        List<RoleCapabilityLabelDO> roleCapabilityLabelDOS = robotCapabilityLabelMapper.selectByRobotIds(roleIds);

        // 获取功能 ID 构建列表查询能力标签表
        List<Long> capabilityLabelIds = roleCapabilityLabelDOS.stream()
                .map(RoleCapabilityLabelDO::getCapabilityLabelId)
                .distinct()
                .toList();

        // 批量查询能力标签
        List<CapabilityLabelDO> capabilityLabels = capabilityLabelMapper.selectByIds(capabilityLabelIds);

        // 构建能力标签 Map
        Map<Long, CapabilityLabelDO> capabilityLabelDOMap = capabilityLabels.stream()
                .collect(Collectors.toMap(CapabilityLabelDO::getId, Function.identity()));

        // 构建智能体ID 和 能力标签 ID Map
        Map<Long, List<Long>> robotIdAndCapabilityIdsMap = roleCapabilityLabelDOS.stream()
                .collect(Collectors.groupingBy(
                        RoleCapabilityLabelDO::getRoleId,
                        Collectors.mapping(RoleCapabilityLabelDO::getCapabilityLabelId, Collectors.toList())));

        // 构建返参列表
        List<FindRolePageListRspVO> findRolePageListRspVOS = Lists.newArrayList();

        roleDOS.forEach(robotDO -> {
            // 获取智能体 ID
            Long id = robotDO.getId();

            // 获取该智能体的能力标签列表
            List<Long> capabilityLabelList = robotIdAndCapabilityIdsMap.get(id);

            // 构建返回值中的能力标签列表
            List<CapabilityLabelDTO> capabilityLabelDTOList = Lists.newArrayList();

            if (CollUtil.isNotEmpty(capabilityLabelList)) {
                // 遍历该智能体的能力标签列表
                capabilityLabelList.forEach(capabilityLabelId -> {
                    // 获取能力标签
                    CapabilityLabelDO capabilityLabelDO = capabilityLabelDOMap.get(capabilityLabelId);

                    if (Objects.nonNull(capabilityLabelDO)) {
                        // 构建能力标签
                        CapabilityLabelDTO capabilityLabelDTO = CapabilityLabelDTO.builder()
                                .code(capabilityLabelDO.getCode())
                                .name(capabilityLabelDO.getName())
                                .build();
                        // 添加到列表
                        capabilityLabelDTOList.add(capabilityLabelDTO);
                    }
                });
            }

            // 构建返回值
            FindRolePageListRspVO findRolePageListRspVO = FindRolePageListRspVO.builder()
                    .id(id)
                    .nickname(robotDO.getNickname())
                    .avatar(robotDO.getAvatar())
                    .introduction(robotDO.getIntroduction())
                    .fullBodyImage(robotDO.getFullBodyImage())
                    .greetingText(robotDO.getGreetingText())
                    .capabilityLabels(capabilityLabelDTOList)
                    .build();

            findRolePageListRspVOS.add(findRolePageListRspVO);
        });

        return PageResponse.success(roleDOPage, findRolePageListRspVOS);
    }

    /**
     * 查询智能体详情
     *
     * @param robotId
     * @return
     */
    @Override
    public Response<?> findById(Long robotId) {
        // 查询智能体
        RoleDO roleDO = robotMapper.selectById(robotId);

        // 智能体不存在
        if (Objects.isNull(roleDO)) {
            throw new BizException(ResponseCodeEnum.ROLE_NOT_EXISTED);
        }

        // 查询智能体支持的能力标签
        List<CapabilityLabelDTO> capabilityLabelDTOList = findRoleCapabilityLabelByRobotId(robotId);

        // 智能体必有文本生成模型，查询该智能体支持的文本生成模型
        CompletableFuture<List<RoleTextVO>> textModelCompletableFuture = CompletableFuture
                .supplyAsync(() -> findRoleTextModelsByRobotId(roleDO.getId()), threadPoolTaskExecutor);

        // 构建异步线程查询智能体对应能力模型信息
        CompletableFuture<List<RoleSoundDTO>> robotSoundCompletableFuture = CompletableFuture.completedFuture(null);

        for (CapabilityLabelDTO capabilityLabelDTO : capabilityLabelDTOList) {
            // 获取能力标签编码
            String code = capabilityLabelDTO.getCode();

            // 获取能力标签枚举
            CapabilityLabelEnum capabilityLabelEnum = CapabilityLabelEnum.getCapabilityLabelEnum(code);

            switch (capabilityLabelEnum) {
                case TTS -> robotSoundCompletableFuture = CompletableFuture
                        .supplyAsync(() -> findRobotSoundModelsByRobotId(roleDO), threadPoolTaskExecutor);
            }
        }

        // 构建最终的智能体语音模型 CompletableFuture
        CompletableFuture<List<RoleSoundDTO>> finalRobotSoundCompletableFuture = robotSoundCompletableFuture;

        // 执行 CompletableFuture
        CompletableFuture<FindRoleByIdReqVO> resultCompletableFuture = CompletableFuture
                .allOf(textModelCompletableFuture, finalRobotSoundCompletableFuture)
                .thenApply(v -> {
                    // 获取异步执行结果
                    List<RoleTextVO> textModelDOS = textModelCompletableFuture.join();
                    List<RoleSoundDTO> roleSoundDTOS = finalRobotSoundCompletableFuture.join();

                    // 进行反参
                    return FindRoleByIdReqVO.builder()
                            .roleId(roleDO.getId())
                            .nickname(roleDO.getNickname())
                            .avatar(roleDO.getAvatar())
                            .introduction(roleDO.getIntroduction())
                            .fullBodyImage(roleDO.getFullBodyImage())
                            .greetingText(roleDO.getGreetingText())
                            .textModels(textModelDOS)
                            .soundModels(roleSoundDTOS)
                            .build();
                });

        // 获取结果
        FindRoleByIdReqVO findRoleByIdReqVO = resultCompletableFuture.join();
        return Response.success(findRoleByIdReqVO);
    }

    /**
     * 查询智能体文本模型
     *
     * @param roleId
     * @return
     */
    @Override
    public Response<?> findRoleTextModelById(Long roleId) {
        // 查询智能体文本模型
        List<RoleTextVO> roleTextDTOS = findRoleTextModelsByRobotId(roleId);

        return Response.success(roleTextDTOS);
    }

    /**
     * 流式对话
     *
     * @param aiRoleChatReqVO
     * @return
     */
    @Override
    public Flux<AIResponse> chat(AIRoleChatReqVO aiRoleChatReqVO) {
        // 获取角色名称
        String roleName = aiRoleChatReqVO.getRoleName();

        // 获取角色策略
        RoleStrategy strategy = roleStrategyFactory.getStrategy(roleName);

        // 不支持的角色模型，返回错误信息
        if (Objects.isNull(strategy)) {
            return Flux.error(new BizException(ResponseCodeEnum.TEXT_MODEL_NOT_EXISTED));
        }

        // 构建 AIChatRequest
        AIChatRequest aiChatRequest = new AIChatRequest(aiRoleChatReqVO);

        return strategy.handleStreamResponse(aiChatRequest);
    }

    /**
     * 生成声音
     *
     * @param soundGenerationReqVO
     * @return
     */
    @Override
    public Response<?> soundGeneration(SoundGenerationReqVO soundGenerationReqVO) {
        // 获取角色名称
        String roleName = soundGenerationReqVO.getRoleName();
        // 获取语言
        String language = soundGenerationReqVO.getLanguage();

        // 构建 TTS 请求参数
        TTSRequest ttsRequest = TTSRequest.builder()
                .model(soundGenerationReqVO.getSoundModel())
                .version(soundGenerationReqVO.getSoundModelVersion())
                .text(soundGenerationReqVO.getText())
                .roleName(roleName)
                .promptLang(language)
                .textLang(language)
                .emotion(soundGenerationReqVO.getEmotion())
                .build();

        // 获取对应的角色策略
        RoleStrategy strategy = roleStrategyFactory.getStrategy(roleName);

        // 不支持的角色模型，返回错误信息
        if (Objects.isNull(strategy)) {
            throw new BizException(ResponseCodeEnum.ROLE_NOT_EXISTED);
        }

        // 调用角色策略生成声音链接
        String audioUrl = strategy.soundGeneration(ttsRequest);

        // 发送事件, 异步处理
        eventPublisher.publishEvent(RoleServiceSoundGenerationEvent.builder()
                .id(soundGenerationReqVO.getId())
                .audioUrl(audioUrl)
                .build());

        return Response.success(audioUrl);
    }

    /**
     * 新建角色对话
     *
     * @param newRoleChatReqVO
     * @return
     */
    @Override
    public Response<?> newRoleChat(NewRoleChatReqVO newRoleChatReqVO) {
        // 获取角色 ID
        Long roleId = newRoleChatReqVO.getRoleId();
        // TODO: 获取登录用户 ID
        Long userId = 1L;

        // 查询角色
        RoleDO roleDO = robotMapper.selectById(roleId);

        // 角色不存在，返回错误信息
        if (Objects.isNull(roleDO)) {
            throw new BizException(ResponseCodeEnum.ROLE_NOT_EXISTED);
        }

        // 查询在之前该用户是否有与该角色对过话
        ChatDO chatDO = chatMapper.selectByUserIdAndRoleId(userId, roleId);

        // 该用户没有与该角色对话过
        if (Objects.isNull(chatDO)) {
            // 生成对话 UUID
            String uuid = UUID.randomUUID().toString();

            // 创建新的对话
            ChatDO newChatDO = ChatDO.builder()
                    .roleId(roleId)
                    .userId(userId)
                    .uuid(uuid)
                    // 对话概要默认为角色名称
                    .summary(roleDO.getNickname())
                    .favorAbility(0)
                    .isTop(false)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();

            // 创建对话消息
            ChatMessageDO chatMessageDO = ChatMessageDO.builder()
                    .chatUuid(uuid)
                    .audioUrl(null)
                    // 初始消息内容存入角色的开场白
                    .content(roleDO.getGreetingText())
                    // 角色设置为助手
                    .role(MessageType.ASSISTANT.getValue())
                    .createTime(LocalDateTime.now())
                    .build();

            // 这里使用编程式事务进行原子性操作数据库
            transactionTemplate.execute(status -> {
                try {
                    // 插入对话
                    chatMapper.insert(newChatDO);
                    // 插入对话消息
                    chatMessageMapper.insert(chatMessageDO);

                    return true;
                } catch (Exception ex) {
                    // 标记事务为回滚
                    status.setRollbackOnly();
                    log.error("", ex);
                }
                return false;
            });

            // 创建返回参数
            NewRoleChatRspVO newRoleChatRspVO = NewRoleChatRspVO.builder()
                    .roleId(roleId)
                    .summary(roleDO.getNickname())
                    .roleAvatar(roleDO.getAvatar())
                    .uuid(uuid)
                    .build();

            return Response.success(newRoleChatRspVO);
        }
        // 该用户已经与该角色对话过，只返回对话的 uuid 让前端进行跳转
        return Response.success(NewRoleChatRspVO.builder().uuid(chatDO.getUuid()).build());
    }

    /**
     * 查询智能体能力标签
     *
     * @param robotId
     * @return
     */
    private List<CapabilityLabelDTO> findRoleCapabilityLabelByRobotId(Long robotId) {
        // 先查询该智能体的能力标签
        List<RoleCapabilityLabelDO> roleCapabilityLabelDOS = robotCapabilityLabelMapper.selectByRobotId(robotId);

        // 获取能力标签 ID
        List<Long> capabilityLabelIds = roleCapabilityLabelDOS.stream()
                .map(RoleCapabilityLabelDO::getCapabilityLabelId)
                .distinct()
                .toList();

        // 构建反参能力标签列表，用与后面查询 AI 能力后进行存储
        List<CapabilityLabelDTO> capabilityLabelDTOList = Lists.newArrayList();

        // 该智能体的能力标签列表不为空
        if (CollUtil.isNotEmpty(capabilityLabelIds)) {
            // 批量查询能力标签
            List<CapabilityLabelDO> capabilityLabels = capabilityLabelMapper.selectByIds(capabilityLabelIds);

            // 构建能力标签 Map
            Map<Long, CapabilityLabelDO> capabilityLabelDOMap = capabilityLabels.stream()
                    .collect(Collectors.toMap(CapabilityLabelDO::getId, Function.identity()));

            roleCapabilityLabelDOS.forEach(roleCapabilityLabelDO -> {
                // 获取能力标签 ID
                Long capabilityLabelId = roleCapabilityLabelDO.getCapabilityLabelId();
                // 获取能力标签
                CapabilityLabelDO capabilityLabelDO = capabilityLabelDOMap.get(capabilityLabelId);

                if (Objects.nonNull(capabilityLabelDO)) {
                    // 构建能力标签
                    CapabilityLabelDTO capabilityLabelDTO = CapabilityLabelDTO.builder()
                            .code(capabilityLabelDO.getCode())
                            .name(capabilityLabelDO.getName())
                            .build();

                    // 添加到列表
                    capabilityLabelDTOList.add(capabilityLabelDTO);
                }
            });
        }

        return capabilityLabelDTOList;
    }

    /**
     * 查询智能体的语音模型
     *
     * @param roleDO
     * @return
     */
    private List<RoleSoundDTO> findRobotSoundModelsByRobotId(RoleDO roleDO) {
        // 查询智能体的语音模型
        List<RoleSoundDO> roleSoundDOS = robotSoundMapper.selectByRobotId(roleDO.getId());

        // 该智能体没有语音模型返回空值
        if (CollUtil.isEmpty(roleSoundDOS)) {
            return null;
        }

        // 这里再次通过异步获取智能体语音模型的信息，提升查询速度
        // 查询智能体的语音模型支持的语言
        CompletableFuture<Map<Long, List<LanguageDTO>>> findRobotSoundLanguageCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 获取语音模型 IDS
            List<Long> roleSoundIds = roleSoundDOS.stream()
                    .map(RoleSoundDO::getId)
                    .toList();

            // 批量查询支持语言列表
            List<RoleSoundLanguageDO> roleSoundLanguageDOS = robotSoundLanguageMapper.selectByRobotSoundIds(roleSoundIds);

            // 获取语言 IDS
            List<Long> languageIds = roleSoundLanguageDOS.stream()
                    .map(RoleSoundLanguageDO::getLanguageId)
                    .distinct()
                    .toList();

            // 批量查询语言信息
            List<LanguageDO> languageDOS = languageMapper.selectByIds(languageIds);

            // 构建语言 Map
            Map<Long, LanguageDO> languageDOMap = languageDOS.stream()
                    .collect(Collectors.toMap(LanguageDO::getId, Function.identity()));

            // 构建智能体语音 ID 和 语言 IDS Map
            Map<Long, List<Long>> robotSoundIdAndLanguageIdsMap = roleSoundLanguageDOS.stream()
                    .collect(Collectors.groupingBy(
                            RoleSoundLanguageDO::getRoleSoundId,
                            Collectors.mapping(RoleSoundLanguageDO::getLanguageId, Collectors.toList())));

            // 构建智能体语音 Map
            Map<Long, Map<Long, RoleSoundLanguageDO>> robotSoundLanguageDOMap = roleSoundLanguageDOS.stream()
                    .collect(Collectors.groupingBy(
                            RoleSoundLanguageDO::getRoleSoundId,
                            // 这里通过语言 ID 区分出 角色语音支持的语言信息, 因为一个语音语音可能支持多个语言情况
                            Collectors.toMap(RoleSoundLanguageDO::getLanguageId, Function.identity())));

            // 构建智能体语音 ID 和 语言 DTOs Map
            Map<Long, List<LanguageDTO>> robotSoundIdAndLanguageDTOsMap = Maps.newHashMap();

            roleSoundIds.forEach(robotSoundId -> {
                // 获取该智能体语音的语言 ID 列表
                List<Long> languageIdList = robotSoundIdAndLanguageIdsMap.get(robotSoundId);
                // 获取该智能体语音的语言信息
                Map<Long, RoleSoundLanguageDO> roleSoundIdAndRoleSoundLanguageDOMap = robotSoundLanguageDOMap.get(robotSoundId);

                // 语言 DTO 列表
                List<LanguageDTO> languageDTOS = Lists.newArrayList();

                // 遍历语言 ID 构建语言 DTO 列表
                languageIdList.forEach(languageId -> {
                    // 获取语言信息
                    LanguageDO languageDO = languageDOMap.get(languageId);

                    // 获取该角色语音的语言支持信息
                    RoleSoundLanguageDO roleSoundLanguageDO = roleSoundIdAndRoleSoundLanguageDOMap.get(languageId);

                    // 构建语言 DTO
                    LanguageDTO languageDTO = LanguageDTO.builder()
                            .id(languageDO.getId())
                            .name(languageDO.getName())
                            .initialsName(languageDO.getInitialsName())
                            .isDefault(roleSoundLanguageDO.getIsDefault())
                            .build();

                    // 添加到列表
                    languageDTOS.add(languageDTO);
                });

                // 添加到结果
                robotSoundIdAndLanguageDTOsMap.put(robotSoundId, languageDTOS);
            });

            return robotSoundIdAndLanguageDTOsMap;
        }, threadPoolTaskExecutor);

        // 查询对应的语音模型
        CompletableFuture<Map<Long, SoundModelDTO>> findSoundModelCompletableFuture = CompletableFuture.supplyAsync(() -> {
            // 获取语音模型 IDS
            List<Long> soundModelIds = roleSoundDOS.stream()
                    .map(RoleSoundDO::getSoundModelId)
                    .distinct()
                    .toList();

            // 批量查询语音模型信息
            List<SoundModelDO> soundModelDOS = soundModelMapper.selectByIds(soundModelIds);

            // 构建语音模型 Map
            Map<Long, SoundModelDO> soundModelDOMap = soundModelDOS.stream()
                    .collect(Collectors.toMap(SoundModelDO::getId, Function.identity()));

            // 构建智能体语音 ID 和 语音模型DTO Map
            Map<Long, SoundModelDTO> soundModelIdAndSoundModelDTOMap = Maps.newHashMap();

            soundModelIds.forEach(soundModelId -> {
                // 获取该智能体语音的语音模型信息
                SoundModelDO soundModelDO = soundModelDOMap.get(soundModelId);

                // 构建语音模型 DTO
                SoundModelDTO soundModelDTO = SoundModelDTO.builder()
                        .id(soundModelDO.getId())
                        .name(soundModelDO.getName())
                        .description(soundModelDO.getDescription())
                        .build();
                // 添加到结果
                soundModelIdAndSoundModelDTOMap.put(soundModelId, soundModelDTO);
            });

            return soundModelIdAndSoundModelDTOMap;
        }, threadPoolTaskExecutor);

        // 处理获取的语音模型和语言信息
        CompletableFuture<List<RoleSoundDTO>> robotSoundModelCompletableFuture = CompletableFuture
                .allOf(findRobotSoundLanguageCompletableFuture, findSoundModelCompletableFuture)
                .thenApplyAsync(v -> {
                    // 获取异步结果
                    Map<Long, List<LanguageDTO>> robotSoundIdAndLanguageDTOsMap = findRobotSoundLanguageCompletableFuture.join();
                    Map<Long, SoundModelDTO> robotSoundIdAndSoundModelDTOMap = findSoundModelCompletableFuture.join();

                    // 智能体支持声音模型列表
                    List<RoleSoundDTO> soundModels = Lists.newArrayList();

                    roleSoundDOS.forEach(roleSoundDO -> {
                        // 获取 ID
                        Long robotSoundId = roleSoundDO.getId();
                        // 获取该智能体语音的语音模型 ID
                        Long soundModelId = roleSoundDO.getSoundModelId();

                        List<LanguageDTO> languageDTOS = robotSoundIdAndLanguageDTOsMap.get(robotSoundId);
                        SoundModelDTO soundModelDTO = robotSoundIdAndSoundModelDTOMap.get(soundModelId);

                        // 构建智能体语音模型 DTO
                        RoleSoundDTO roleSoundDTO = RoleSoundDTO.builder()
                                .id(robotSoundId)
                                .modelName(soundModelDTO.getName())
                                .modelDescription(soundModelDTO.getDescription())
                                .soundModelName(roleSoundDO.getName())
                                .version(roleSoundDO.getVersion())
                                .isDefault(roleSoundDO.getIsDefault())
                                .languages(languageDTOS)
                                .build();

                        soundModels.add(roleSoundDTO);
                    });

                    return soundModels;
                });
        return robotSoundModelCompletableFuture.join();
    }

    /**
     * 查询智能体的语言模型
     *
     * @param roleId
     * @return
     */
    private List<RoleTextVO> findRoleTextModelsByRobotId(Long roleId) {
        // 查询智能体的文本生成模型
        List<RoleTextDO> roleTextDOS = robotTextMapper.selectByRobotId(roleId);

        // 转化成文本生成模型 IDS
        List<Long> textModelIds = roleTextDOS.stream().map(RoleTextDO::getTextModelId).toList();

        // 批量查询文本生成模型
        List<TextModelDO> textModelDOS = textModelMapper.selectByIds(textModelIds);

        // 构建文本生成模型 Map
        Map<Long, TextModelDO> textModelDOMap = textModelDOS.stream()
                .collect(Collectors.toMap(TextModelDO::getId, Function.identity()));

        // 构建文本生成模型列表
        List<RoleTextVO> roleTextVO = roleTextDOS.stream()
                .map(roleTextDO -> {
                    // 获取文本生成模型信息
                    TextModelDO textModelDO = textModelDOMap.get(roleTextDO.getTextModelId());

                    // 构建 DTO
                    return RoleTextVO.builder()
                            .id(textModelDO.getId())
                            .name(textModelDO.getName())
                            .description(textModelDO.getDescription())
                            .provider(textModelDO.getProvider())
                            .isDefault(roleTextDO.getIsDefault())
                            // 当角色是 "黑夜" 时，才显示深度思考功能
                            .isSelectThink(roleId == 1 ? textModelDO.getIsSelectThink() : false)
                            .build();
                })
                .toList();

        return roleTextVO;
    }
}
